package com.zzyl.common.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;

public class AsciiArtUtils {

    // ASCII 字符集，从暗到亮
    private static final String ASCII_CHARS_BW = "@%#*+=-:. ";
    private static final String ASCII_CHARS_COLOR = " .,:;+*?%S#@";
    
    /**
     * 将图片文件转换为ASCII艺术并打印到控制台（黑白）
     * @param filePath 图片文件路径
     * @param width 输出宽度（字符数）
     * @throws IOException
     */
    public static void printAsciiArt(String filePath, int width) throws IOException {
        BufferedImage image = ImageIO.read(new File(filePath));
        printAsciiArt(image, width, false);
    }

    /**
     * 将URL图片转换为ASCII艺术并打印到控制台
     * @param imageUrl 图片URL
     * @param width 输出宽度（字符数）
     * @param colored 是否使用彩色输出
     * @throws IOException
     */
    public static void printAsciiArt(URL imageUrl, int width, boolean colored) throws IOException {
        BufferedImage image = ImageIO.read(imageUrl);
        printAsciiArt(image, width, colored);
    }

    /**
     * 核心转换方法
     * @param image 图片对象
     * @param width 输出宽度（字符数）
     * @param colored 是否使用彩色输出
     */
    public static void printAsciiArt(BufferedImage image, int width, boolean colored) {
        if (image == null) {
            System.out.println("图片加载失败");
            return;
        }

        int height = (int) ((double) image.getHeight() / image.getWidth() * width * 0.5);
        BufferedImage resizedImage = resizeImage(image, width, height);

        StringBuilder asciiArt = new StringBuilder();
        String charset = colored ? ASCII_CHARS_COLOR : ASCII_CHARS_BW;

        for (int y = 0; y < resizedImage.getHeight(); y++) {
            for (int x = 0; x < resizedImage.getWidth(); x++) {
                Color color = new Color(resizedImage.getRGB(x, y));
                int brightness = getBrightness(color);
                int index = brightness * (charset.length() - 1) / 255;
                char asciiChar = charset.charAt(index);

                if (colored) {
                    // 使用ANSI颜色代码
                    String colorCode = getAnsiColorCode(color);
                    asciiArt.append(colorCode).append(asciiChar);
                } else {
                    asciiArt.append(asciiChar);
                }
            }
            asciiArt.append("\n");
        }

        // 重置ANSI颜色
        if (colored) {
            asciiArt.append("\u001B[0m");
        }

        System.out.println(asciiArt.toString());
    }

    private static BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {
        Image tmp = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        Graphics2D g2d = resizedImage.createGraphics();
        g2d.drawImage(tmp, 0, 0, null);
        g2d.dispose();
        
        return resizedImage;
    }

    private static int getBrightness(Color color) {
        return (color.getRed() * 77 + color.getGreen() * 151 + color.getBlue() * 28) >> 8;
    }

    private static String getAnsiColorCode(Color color) {
        // 使用8位ANSI颜色（256色模式）
        int r = color.getRed();
        int g = color.getGreen();
        int b = color.getBlue();
        return String.format("\u001B[38;2;%d;%d;%dm", r, g, b);
    }

    /**
     * 测试方法
     */
    public static void main(String[] args) {
        try {
            // 示例用法
            System.out.println("黑白ASCII艺术:");
            printAsciiArt("src/main/resources/static/lazy-sheep.png", 80);
            
            System.out.println("\n彩色ASCII艺术:");
            printAsciiArt(new URL("https://example.com/image.jpg"), 100, true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}